import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;


public final class Decompress2 {

	public static void main(String[] args) throws IOException {
		File inputFile = new File("C:/Users/aj33460/Desktop/lab1//compress_t.txt");
		File outputFile = new File("C:/Users/aj33460/Desktop/lab1/uncompress_t.txt");

		BitInputStream in = new BitInputStream(new BufferedInputStream(new FileInputStream(inputFile)));
		OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
		try {
			decompress(in, out);
		} finally {
			out.close();
			in.close();
		}
	}


	static void decompress(BitInputStream in, OutputStream out) throws IOException {
		int[] initFreqs = new int[257];
		Arrays.fill(initFreqs, 1);

		TableFreq freqTable = new TableFreq(initFreqs);
		Decoder dec = new Decoder(in);
		dec.codeTree = freqTable.buildCodeTree();
		int count = 0;
		while (true) {
			int symbol = dec.read();
			if (symbol == 256) // EOF symbol
				break;
			out.write(symbol);

			freqTable.increment(symbol);
			count++;
			if (count < 262144 && isPowerOf2(count) || count % 262144 == 0) // Update code tree
				dec.codeTree = freqTable.buildCodeTree();
			if (count % 262144 == 0) // Reset frequency table
				freqTable = new TableFreq(initFreqs);
		}
	}


	private static boolean isPowerOf2(int x) {
		return x > 0 && (x & -x) == x;
	}

}